﻿//******************************
//Project by: Michael Wolfe
//Project Date: 30 March 2011
//******************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BattlefieldOrcVsGoblin
{

    //This class represents the creatures that will move and fight.
    class Humanoid
    {

        //Initialize the shared variables among the class.
        public sbyte sbyHealth;
        public byte bytMovement;
        public sbyte sbyStartPosition;
        public sbyte sbyCurrentPosition;
        public byte bytAlignment;
        public string strName;
        List<Weapon> Sheath = new List<Weapon>();

        //This is the constructor that is called when a new instance of the Class is made.
        public Humanoid()
        {
            sbyHealth = 10;
            bytMovement = 5;
            sbyStartPosition = 0;
            sbyCurrentPosition = sbyStartPosition;
            strName = "Humanoid";
        }

        //Add a weapon reference to the Sheath List.
        public void AddWeapon(Weapon newWeapon)
        {
            Sheath.Add(newWeapon);
        }

        //Use the weapon reference in the Sheath to damage the health of the target creature.
        public void Attack(Humanoid newHumanoid)
        {
            foreach (Weapon newWeapon in Sheath)
            {
                Random rand1 = new Random();
                byte bytDamage = Convert.ToByte(rand1.Next(1,newWeapon.bytWeaponDamage));
                newWeapon.bytDamageDone = bytDamage;
                newHumanoid.sbyHealth = Convert.ToSByte(newHumanoid.sbyHealth - bytDamage);
            }
        }
    }

    //This is a general Class for the Weapon objects.
    class Weapon
    {
        public byte bytWeaponDamage;
        public byte bytDamageDone;
        public string strName;
    }

    //This is a subclass of Weapon.
    class Shortsword : Weapon
    {

        //Constructor
        public Shortsword()
        {
            bytWeaponDamage = 6;
            strName = "Shortsword";
        }
    }

    //This is a subclass of Weapon.
    class Mace : Weapon
    {

        //Constructor
        public Mace()
        {
            bytWeaponDamage = 5;
            strName = "Mace";
        }
    }

    //This Class contains the Main Static.
    class Program
    {

        //Start the program.
        public static void Main(string[] args)
        {

            //Add a new instance of Humanoid named "Orc" and set its variables.
            Humanoid humOrc = new Humanoid();
            humOrc.bytAlignment = 1;
            humOrc.sbyHealth = 30;
            humOrc.bytMovement = 6;
            humOrc.sbyStartPosition = 100;
            humOrc.sbyCurrentPosition = humOrc.sbyStartPosition;
            humOrc.strName = "Orc";

            //Add a new instance of Shortsword.
            Shortsword sword1 = new Shortsword();

            //Add sword1 to Orc's sheath.
            humOrc.AddWeapon(sword1);

            //Add a new instance of Humanoid named "Goblin" and set its variables.
            Humanoid humGoblin = new Humanoid();
            humGoblin.bytAlignment = 2;
            humGoblin.sbyHealth = 30;
            humGoblin.bytMovement = 8;
            humGoblin.strName = "Goblin";

            //Add a new instance of Mace.
            Mace mace1 = new Mace();

            //Add mace1 to Goblin's sheath.
            humGoblin.AddWeapon(mace1);

            //Write an introduction to the program.
            Console.WriteLine("Welcome to Turn-Based Orc versus Goblin.");
            Console.WriteLine("");
            Console.WriteLine(humGoblin.strName + " and " + humOrc.strName
                + " are 100 feet from each other and wish to kill each other.");
            Console.WriteLine(humGoblin.strName + " moves " + humGoblin.bytMovement
                + " feet per second and carries " + mace1.strName + ".");
            Console.WriteLine(humOrc.strName + " moves " + humOrc.bytMovement
                + " feet per second and carries " + sword1.strName + ".");
            Console.WriteLine("");
            Console.WriteLine("Each combatant will take turns carrying out their action.");
            Console.WriteLine("To see the next action in the sequence, hit Enter.");
            Console.ReadLine();

            //Write the starting health and location of the two combatants.
            Console.WriteLine(humOrc.strName + " has " + humOrc.sbyHealth + " health and is located at position "
                + humOrc.sbyCurrentPosition + ".");
            Console.WriteLine(humGoblin.strName + " has " + humGoblin.sbyHealth + " health and is located at position "
                + humGoblin.sbyCurrentPosition + ".");
            Console.ReadLine();

            //Initilialize the EndLoop variable.
            byte bytEndLoop = 0;

            //Start a loop to determine the outcome of the combat.
            while(bytEndLoop < 1)
            {

                //Both combatants are alive.  Begin the combat sequence.
                //It is the first combatant's turn.
                if (humOrc.sbyHealth > 0 && humGoblin.sbyHealth > 0)
                {

                    //The two combatants are not at the same location.
                    //It is the first combatant's turn.
                    if (humOrc.sbyCurrentPosition != humGoblin.sbyCurrentPosition)
                    {

                        //The first combatant cannot reach the second combatant in one turn.
                        //The first combatant moves as far as it can in one turn towards the
                        //second combatant.  The first combatant ends its turn.
                        if (humOrc.sbyCurrentPosition - humGoblin.sbyCurrentPosition > humOrc.bytMovement)
                        {
                            humOrc.sbyCurrentPosition = Convert.ToSByte(humOrc.sbyCurrentPosition - humOrc.bytMovement);
                            Console.WriteLine(humOrc.strName + " moves " + humOrc.bytMovement
                            + " feet to position " + humOrc.sbyCurrentPosition + ".");
                            Console.WriteLine(humOrc.strName + " is "
                                + (humOrc.sbyCurrentPosition - humGoblin.sbyCurrentPosition)
                                + " feet from " + humGoblin.strName + ".");
                            Console.ReadLine();
                        }

                        //The first combatant can reach the second combatant in one turn.
                        //The first combatant moves to the location of the second combatant
                        //and ends its turn.
                        else
                        {
                            byte bytMove = Convert.ToByte(humOrc.sbyCurrentPosition - humGoblin.sbyCurrentPosition);
                            humOrc.sbyCurrentPosition = Convert.ToSByte(humGoblin.sbyCurrentPosition);
                            Console.WriteLine(humOrc.strName + " moves " + bytMove + " feet to position "
                                + humOrc.sbyCurrentPosition + ".");
                            Console.WriteLine(humOrc.strName + " is at the same position as "
                                + humGoblin.strName + ".");
                            Console.ReadLine();
                        }
                    }

                    //The combatants are at the same location and it is the first combatant's turn.
                    else
                    {

                        //Both combatants are alive.  The first combatant attacks the second and
                        //ends its turn.
                        if (humOrc.sbyHealth > 0 && humGoblin.sbyHealth > 0)
                        {
                            Console.WriteLine(humOrc.strName + " attacks " + humGoblin.strName
                                + " with " + sword1.strName + ".");
                            humOrc.Attack(humGoblin);
                            Console.WriteLine(humGoblin.strName + " takes " + sword1.bytDamageDone + " damage.");
                            Console.WriteLine(humGoblin.strName + " has " + humGoblin.sbyHealth + " health.");
                            Console.ReadLine();
                        }
                    }

                    //Both combatants are still alive. It is the second combatant's turn.
                    //The combatants are not at the same location.
                    if (humGoblin.sbyCurrentPosition != humOrc.sbyCurrentPosition)
                    {

                        //The second combatant cannot reach the first combatant in one turn.
                        //The second combatant moves as far as it can in one turn towards the 
                        //first combatant.  The second combatant ends its turn.
                        if (humOrc.sbyCurrentPosition - humGoblin.sbyCurrentPosition > humGoblin.bytMovement)
                        {
                            humGoblin.sbyCurrentPosition = Convert.ToSByte(humGoblin.sbyCurrentPosition + humGoblin.bytMovement);
                            Console.WriteLine(humGoblin.strName + " moves " + humGoblin.bytMovement
                            + " feet to position " + humGoblin.sbyCurrentPosition + ".");
                            Console.WriteLine(humGoblin.strName + " is "
                                + (humOrc.sbyCurrentPosition - humGoblin.sbyCurrentPosition)
                                + " feet from " + humOrc.strName + ".");
                            Console.ReadLine();
                        }

                        //The second combatant can reach the first combatant in one turn.
                        //The second combatant moves to the location of the first combatant.
                        //The second combatant ends its turn.
                        else
                        {
                            byte bytMove = Convert.ToByte(humOrc.sbyCurrentPosition - humGoblin.sbyCurrentPosition);
                            humGoblin.sbyCurrentPosition = Convert.ToSByte(humOrc.sbyCurrentPosition);
                            Console.WriteLine(humGoblin.strName + " moves " + bytMove + " feet to position "
                                + humGoblin.sbyCurrentPosition + ".");
                            Console.WriteLine(humGoblin.strName + " is at the same position as "
                                + humOrc.strName + ".");
                            Console.ReadLine();
                        }
                    }

                    //The second combatant is at the same location as the first combatant.
                    //It is the second combatant's turn.
                    else
                    {

                        //Both combatants are alive.  The second combatant attacks the first
                        //combatant and ends its turn.
                        if (humGoblin.sbyHealth > 0 && humOrc.sbyHealth > 0)
                        {
                            Console.WriteLine(humGoblin.strName + " attacks " + humOrc.strName
                                + " with " + mace1.strName + ".");
                            humGoblin.Attack(humOrc);
                            Console.WriteLine(humOrc.strName + " takes " + mace1.bytDamageDone + " damage.");
                            Console.WriteLine(humOrc.strName + " has " + humOrc.sbyHealth + " health.");
                            Console.ReadLine();
                        }
                    }
                }

                //One or more combatants is dead.  The combat is over.  It is time to
                //determine the results.
                else
                {

                    //The first combatant is alive, and the second combatant is dead.
                    //The first combatant wins.
                    if (humOrc.sbyHealth > 0 && humGoblin.sbyHealth <= 0)
                    {
                        Console.WriteLine(humGoblin.strName + " is dead.");
                        Console.WriteLine(humOrc.strName + " wins.");
                        bytEndLoop = 1;
                        Console.WriteLine("Hit Enter to exit the Console.");
                        Console.ReadLine();
                    }
                    else
                    {

                        //The second combatant is alive, and the first combatant is dead.
                        //The second combatant wins.
                        if (humGoblin.sbyHealth > 0 && humOrc.sbyHealth <= 0)
                        {
                            Console.WriteLine(humOrc.strName + " is dead.");
                            Console.WriteLine(humGoblin.strName + " wins.");
                            bytEndLoop = 1;
                            Console.WriteLine("Hit Enter to exit the Console.");
                            Console.ReadLine();
                        }

                        //Both combatants are dead.  Neither combatant wins.
                        else
                        {
                            Console.WriteLine(humOrc.strName + " and "
                                + humGoblin.strName + " are dead.");
                            Console.WriteLine("The match is a draw.");
                            Console.WriteLine("Hit Enter to exit the Console.");
                            Console.WriteLine("");
                            bytEndLoop = 1;
                            Console.ReadLine();
                        }
                    }
                }
            }
        }

    }
}
